package com.tanhua.server.service;

import com.tanhua.commons.exception.TanHuaException;
import com.tanhua.commons.templates.OssTemplate;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.mongo.Visitor;
import com.tanhua.domain.vo.*;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.dubbo.api.mongo.CommentApi;
import com.tanhua.dubbo.api.mongo.PublishApi;
import com.tanhua.dubbo.api.mongo.VisitorsApi;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.server.utils.RelativeDateFormat;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 圈子业务逻辑处理层
 */
@Service
public class MomentService {

    @Reference
    private PublishApi publishApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Reference
    private VisitorsApi visitorsApi;


    @Autowired
    private OssTemplate ossTemplate;

    @Reference
    private CommentApi commentApi;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 发布动态
     */
    public void savePublish(MultipartFile[] imageContent, PublishVo publishVo) {
        try {
            Long userId = UserHolder.getUserId();
            //1.调用Oss组件上图图片
            List<String> medias = new ArrayList<>();
            if(imageContent != null) {
                for (MultipartFile file : imageContent) {
                    String imageUrl = ossTemplate.upload(file.getOriginalFilename(), file.getInputStream());
                    medias.add(imageUrl);
                }
                publishVo.setMedias(medias);//图片urls
            }
            publishVo.setUserId(userId);//当前发布动态用户id
            String publishId = publishApi.savePublish(publishVo);
            //发送消息到中间件
            rocketMQTemplate.convertAndSend("tanhua-publish",publishId);
        } catch (IOException e) {
            throw new TanHuaException(ErrorResult.error());
        }
    }

    /**
     * 好友动态
     */
    public PageResult<MomentVo> queryPublishByPage(int page, int pagesize) {
        PageResult<MomentVo> voPageResult = new PageResult<>();

        Long userId = UserHolder.getUserId();
        //a.调用服务：分页查询发布表数据（分别查询好友时间线表 发布表）
        PageResult<Publish> publishPageResult = publishApi.queryPublishByPage(page,pagesize,userId);
        if(publishPageResult == null || CollectionUtils.isEmpty(publishPageResult.getItems())){
            return new PageResult<>(0l,10l,0l,0l,null);
        }
        //b.调用服务：根据发布用户id 查询用户信息
        List<Publish> publishList = publishPageResult.getItems();

        //将List<Publish>转为List<MomentVo>
        List<MomentVo>  momentVoList = new ArrayList<>();//返回给app集合
        for (Publish publish : publishList) {
            MomentVo momentVo = new MomentVo();
            Long publishUserId = publish.getUserId();//发布动态用户id
            UserInfo userInfo = userInfoApi.queryUserInfo(publishUserId);
            BeanUtils.copyProperties(userInfo,momentVo);//头像 昵称 性别 年龄
            BeanUtils.copyProperties(publish,momentVo);//文字动态、 点赞 评论 喜欢数


            momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));//图片urls地址
            momentVo.setDistance("1米");//距离1米
            momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));//发布动态时间
            if(!StringUtils.isEmpty(userInfo.getTags())){
                momentVo.setTags(userInfo.getTags().split(","));
            }
            momentVo.setId(publish.getId().toHexString());//动态id
            momentVo.setUserId(userInfo.getId());//当前发布动态用户id

            String key = "comment_"+userId+"_"+publish.getId().toHexString();
            if(StringUtils.isEmpty(redisTemplate.opsForValue().get(key))){
                momentVo.setHasLiked(0);////是否点赞（1是，0否）
            }else
            {
                momentVo.setHasLiked(1);////是否点赞（1是，0否）
            }
            momentVoList.add(momentVo);
        }
        //c.将以上发布数据与用户信息封装Vo返回
        BeanUtils.copyProperties(publishPageResult,voPageResult);
        voPageResult.setItems(momentVoList);
        return voPageResult;
    }

    /**
     * 推荐动态（陌生人动态）
     */
    public PageResult<MomentVo> queryPublishByRecommendQuanzi(int page, int pagesize) {

        PageResult<MomentVo> voPageResult = new PageResult<>();

        Long userId = UserHolder.getUserId();
        //a.调用服务：分页查询发布表数据（分别查询好友时间线表 发布表）
        PageResult<Publish> publishPageResult = publishApi.queryPublishByRecommendQuanzi(page,pagesize,userId);
        if(publishPageResult == null || CollectionUtils.isEmpty(publishPageResult.getItems())){
            return new PageResult<>(0l,10l,0l,0l,null);
        }
        //b.调用服务：根据发布用户id 查询用户信息
        List<Publish> publishList = publishPageResult.getItems();

        //将List<Publish>转为List<MomentVo>
        List<MomentVo>  momentVoList = new ArrayList<>();//返回给app集合
        for (Publish publish : publishList) {
            MomentVo momentVo = new MomentVo();
            Long publishUserId = publish.getUserId();//发布动态用户id
            UserInfo userInfo = userInfoApi.queryUserInfo(publishUserId);
            BeanUtils.copyProperties(userInfo,momentVo);//头像 昵称 性别 年龄
            BeanUtils.copyProperties(publish,momentVo);//文字动态、 点赞 评论 喜欢数


            momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));//图片urls地址
            momentVo.setDistance("1米");//距离1米
            momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));//发布动态时间
            if(!StringUtils.isEmpty(userInfo.getTags())){
                momentVo.setTags(userInfo.getTags().split(","));
            }
            momentVo.setId(publish.getId().toHexString());//动态id
            momentVo.setUserId(userInfo.getId());//当前发布动态用户id
            String key2 = "love_"+userId+"_"+publish.getId().toHexString();
            if(StringUtils.isEmpty(redisTemplate.opsForValue().get(key2))) {
                momentVo.setHasLoved(0);////是否喜欢（1是，0否）
            }else
            {
                momentVo.setHasLoved(1);////是否喜欢（1是，0否）
            }
            String key = "comment_"+userId+"_"+publish.getId().toHexString();
            if(StringUtils.isEmpty(redisTemplate.opsForValue().get(key))){
                momentVo.setHasLiked(0);////是否点赞（1是，0否）
            }else
            {
                momentVo.setHasLiked(1);////是否点赞（1是，0否）
            }

            momentVoList.add(momentVo);
        }
        //c.将以上发布数据与用户信息封装Vo返回
        BeanUtils.copyProperties(publishPageResult,voPageResult);
        voPageResult.setItems(momentVoList);
        return voPageResult;
    }

    /**
     * 用户动态
     * 1.首页推荐用户列表-点击用户进入会查询用户动态
     * 2.我的模块-我的动态-查看当前用户动态
     */
    public PageResult<MomentVo> queryPublishByAlbum(int page, int pagesize, Long userId) {
        PageResult<MomentVo> voPageResult = new PageResult<>();
        //a.调用服务：分页查询发布表数据（分别查询好友时间线表 发布表）
        PageResult<Publish> publishPageResult = publishApi.queryPublishByAlbum(page,pagesize,userId);
        if(publishPageResult == null || CollectionUtils.isEmpty(publishPageResult.getItems())){
            return new PageResult<>(0l,10l,0l,0l,null);
        }
        //b.调用服务：根据发布用户id 查询用户信息
        List<Publish> publishList = publishPageResult.getItems();

        //将List<Publish>转为List<MomentVo>
        List<MomentVo>  momentVoList = new ArrayList<>();//返回给app集合
        for (Publish publish : publishList) {
            MomentVo momentVo = new MomentVo();
            Long publishUserId = publish.getUserId();//发布动态用户id
            UserInfo userInfo = userInfoApi.queryUserInfo(publishUserId);
            BeanUtils.copyProperties(userInfo,momentVo);//头像 昵称 性别 年龄
            BeanUtils.copyProperties(publish,momentVo);//文字动态、 点赞 评论 喜欢数


            momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));//图片urls地址
            momentVo.setDistance("1米");//距离1米
            momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));//发布动态时间
            if(!StringUtils.isEmpty(userInfo.getTags())){
                momentVo.setTags(userInfo.getTags().split(","));
            }
            momentVo.setId(publish.getId().toHexString());//动态id
            momentVo.setUserId(userInfo.getId());//当前发布动态用户id

            String key = "comment_"+userId+"_"+publish.getId().toHexString();
            if(StringUtils.isEmpty(redisTemplate.opsForValue().get(key))){
                momentVo.setHasLiked(0);////是否点赞（1是，0否）
            }else
            {
                momentVo.setHasLiked(1);////是否点赞（1是，0否）
            }

            momentVoList.add(momentVo);
        }
        //c.将以上发布数据与用户信息封装Vo返回
        BeanUtils.copyProperties(publishPageResult,voPageResult);
        voPageResult.setItems(momentVoList);
        return voPageResult;
    }

    /**
     * 动态点赞
     * publishId:动态id
     */
    public int saveComment(String publishId) {
        Long userId = UserHolder.getUserId();//当前用户id
        //a.服务提供者：点赞服务方法 返回点赞数量
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));//将String类型的发布id 转为ObjectId类型
        comment.setCommentType(1);//评论类型，1-点赞，2-评论，3-喜欢
        comment.setPubType(1);//评论内容类型： 1-对动态操作 2-对视频操作 3-对评论操作
        comment.setUserId(userId);//当前点赞用户id
        if(comment.getPubType() == 1){
            //根据发布id查询发布表 获取userId(PublishUserId)
            Publish publish = publishApi.querySinglePublish(publishId);
            comment.setPublishUserId(publish.getUserId());//被评论的用户id
        }
        int likeCount = commentApi.saveComment(comment);
        //b.将点赞记录写入redis
        String key = "comment_"+userId+"_"+publishId;//保证唯一 业务前缀标识+userId+publishId
        redisTemplate.opsForValue().set(key,"1");
        //c.将点赞数封装返回给app展示
        return likeCount;
    }

    /**
     * 动态取消点赞
     * publishId:动态id
     */
    public int removeComment(String publishId) {
        Long userId = UserHolder.getUserId();
        //a.服务提供者：取消点赞服务方法 返回点赞数量
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));//动态id
        comment.setCommentType(1);//评论类型，1-点赞，2-评论，3-喜欢
        comment.setPubType(1);//评论内容类型： 1-对动态操作 2-对视频操作 3-对评论操作
        comment.setUserId(userId);//userId
        int likeCount = commentApi.removeComment(comment);
        //b.将点赞记录从redis删除
        String key = "comment_"+userId+"_"+publishId;//保证唯一 业务前缀标识+userId+publishId
        redisTemplate.delete(key);
        //c.将点赞数封装返回给app展示
        return likeCount;
    }

    /**
     * 动态喜欢
     * publishId:动态id
     */
    public int saveCommentLove(String publishId) {
        Long userId = UserHolder.getUserId();//当前用户id
        //a.服务提供者：点赞服务方法 返回点赞数量
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));//将String类型的发布id 转为ObjectId类型
        comment.setCommentType(3);//评论类型，1-点赞，2-评论，3-喜欢
        comment.setPubType(1);//评论内容类型： 1-对动态操作 2-对视频操作 3-对评论操作
        comment.setUserId(userId);//当前点赞用户id
        if(comment.getPubType() == 1){
            //根据发布id查询发布表 获取userId(PublishUserId)
            Publish publish = publishApi.querySinglePublish(publishId);
            comment.setPublishUserId(publish.getUserId());//被评论的用户id
        }
        int likeCount = commentApi.saveComment(comment);
        //b.将点赞记录写入redis
        String key = "love_"+userId+"_"+publishId;//保证唯一 业务前缀标识+userId+publishId
        redisTemplate.opsForValue().set(key,"1");
        //c.将点赞数封装返回给app展示
        return likeCount;
    }

    /**
     * 动态取消喜欢
     * publishId:动态id
     */
    public int saveCommentUnLove(String publishId) {
        Long userId = UserHolder.getUserId();
        //a.服务提供者：取消点赞服务方法 返回点赞数量
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));//动态id
        comment.setCommentType(3);//评论类型，1-点赞，2-评论，3-喜欢
        comment.setPubType(1);//评论内容类型： 1-对动态操作 2-对视频操作 3-对评论操作
        comment.setUserId(userId);//userId
        int likeCount = commentApi.removeComment(comment);
        //b.将点赞记录从redis删除
        String key = "love_"+userId+"_"+publishId;//保证唯一 业务前缀标识+userId+publishId
        redisTemplate.delete(key);
        //c.将点赞数封装返回给app展示
        return likeCount;
    }

    /**
     * 单条动态查询
     */
    public MomentVo querySinglePublish(String publishId) {
        //a.调用服务：根据发布id查询动态发布表
        Publish publish = publishApi.querySinglePublish(publishId);
        if(publish == null){
            return null;
        }
        //b.调用服务：根据发布用户id 查询用户信息
        //将List<Publish>转为List<MomentVo>
        MomentVo momentVo = new MomentVo();
        Long publishUserId = publish.getUserId();//发布动态用户id
        UserInfo userInfo = userInfoApi.queryUserInfo(publishUserId);
        BeanUtils.copyProperties(userInfo,momentVo);//头像 昵称 性别 年龄
        BeanUtils.copyProperties(publish,momentVo);//文字动态、 点赞 评论 喜欢数


        momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));//图片urls地址
        momentVo.setDistance("1米");//距离1米
        momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));//发布动态时间
        if(!StringUtils.isEmpty(userInfo.getTags())){
            momentVo.setTags(userInfo.getTags().split(","));
        }
        momentVo.setId(publish.getId().toHexString());//动态id
        momentVo.setUserId(userInfo.getId());//当前发布动态用户id
        return momentVo;
    }

    /**
     * 谁看过我(查询5条)
     */
    public List<VisitorVo> queryVisitors() {
        List<VisitorVo> list = new ArrayList<>();
        Long userId = UserHolder.getUserId();//当前用户登录id
        //a.查询redis上次登录时间是否存在
        String key="visitors_time_"+userId;
        String lastLoginTime = redisTemplate.opsForValue().get(key);//key:visitors_time_1 value:上次登录的时间

        ///b.如果上次登录时间存在，date（访客访问时间）>上次登录时间5条记录
        List<Visitor> visitorList = new ArrayList<>();
        if(!StringUtils.isEmpty(lastLoginTime)){
            //将String lastLoginTime转为Long lastLoginTime
            long lastLoginTimeLong = Long.parseLong(lastLoginTime);
            visitorList = visitorsApi.queryVisitorsByDate(lastLoginTimeLong,userId);
        }else {
            //c.如果上次登录时间不存在，从所有访客记录中查询5条记录
            visitorList = visitorsApi.queryVisitors(userId);
        }
        for (Visitor visitor : visitorList) {
            VisitorVo visitorVo = new VisitorVo();
            UserInfo userInfo = userInfoApi.queryUserInfo(visitor.getVisitorUserId());
            BeanUtils.copyProperties(userInfo,visitorVo);//头像 昵称 性别 年龄
            visitorVo.setTags(userInfo.getTags().split(","));//标签
            visitorVo.setId(visitor.getVisitorUserId());//访客用户id
            visitorVo.setFateValue(visitor.getScore().intValue());//访客表中缘分值
            list.add(visitorVo);
        }
        //d.将当前登录时间记录redis
        redisTemplate.opsForValue().set(key,System.currentTimeMillis()+"");
        return list;

    }
}
